package cn.lingyangwl.framework.log.integration.resttemplate;

import cn.lingyangwl.framework.core.utils.IpUtils;
import cn.lingyangwl.framework.core.utils.servlet.ServletUtils;
import cn.lingyangwl.framework.core.utils.spring.SpringUtils;
import cn.lingyangwl.framework.log.common.LogCons;
import cn.lingyangwl.framework.log.utils.BraveTracerUtils;
import cn.lingyangwl.framework.log.utils.MDCTraceUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;

/**
 * RestTemplate的拦截器
 *
 * @author shenguangyang
 */
@Slf4j
@Component
public class LogRestTemplateInterceptor implements ClientHttpRequestInterceptor {

    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {

        String traceId = MDCTraceUtils.getTraceId();
        AtomicReference<String> loginId = new AtomicReference<>();
        Optional<HttpServletRequest> servletRequest = ServletUtils.getRequest();
        servletRequest.ifPresent(e -> loginId.set(e.getHeader(LogCons.LOGIN_ID)));

        if(StringUtils.isNotBlank(traceId)) {
            String appName = SpringUtils.getProperty("spring.application.name");
            BraveTracerUtils.addTraceId(request.getHeaders()::add);

            request.getHeaders().add(LogCons.LOGIN_ID, loginId.get());
            request.getHeaders().add(LogCons.PRE_APP_KEY, appName);
            request.getHeaders().add(LogCons.PRE_APP_HOST_NAME, IpUtils.getHostName());
            request.getHeaders().add(LogCons.PRE_APP_IP, IpUtils.getHostIp());
        } else {
            log.debug("[LOG]本地threadLocal变量没有正确传递traceId,本次调用不传递traceId");
        }
        return execution.execute(request, body);
    }
}
